/**************************************************
*
*
  * File Name          : AdcProcess.c
  * Description        : 本文档包含系统运行参数和设置参数的定义源文件
*
***************//////////////////////////////////////////////


#include "LogicProcess.h"
#include "NetAtProcess.h"


uint16_t DITempValue[5][2] = {0};//存储采集的状态
uint16_t DI_i = 0;

/*******DI******/
void DIProcess(void)
{//DI采集
	if(0 == tickstart[TASK_WORK_DI].start)
	{//启动定时器
		Start_Tick(TASK_WORK_DI);
	}
	if((0 != tickstart[TASK_WORK_DI].start)&&(tickstart[TASK_WORK_DI].time > 10))
	{//每10ms采集一次DI状态
		Stop_Tick(TASK_WORK_DI);
		DITempValue[DI_i][0] = ((GPIO_PIN_RESET == HAL_GPIO_ReadPin(DI1_GPIO_Port,DI1_Pin)) ? 1 : 0);
		DITempValue[DI_i][1] = ((GPIO_PIN_RESET == HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin)) ? 1 : 0);
		if(DI_i < 4)
		{
			DI_i++;
		}
		else
		{//每采集5次 进行一次判断状态 达到消抖的作用
			DI_i = 0;
			RunDataConfig->DI0 = (DITempValue[0][0] + DITempValue[1][0] + DITempValue[2][0] + DITempValue[3][0] + DITempValue[4][0] > 2) ? 1 : 0;//DI
			RunDataConfig->Key = (DITempValue[0][1] + DITempValue[1][1] + DITempValue[2][1] + DITempValue[3][1] + DITempValue[4][1] > 2) ? 1 : 0;//按键
		}
	}
}

/*******DO******/

uint16_t DOstate = 0;//DO运行流程
uint16_t LogicState = 0;//判断逻辑状态变化
uint16_t DOOutput = 0;//延时翻转时DO状态
uint16_t POW_Start = 0;//判断是否为通电后的第一次运行

uint16_t DOSetProcess(void)
{
	switch(DOstate)
	{
		case 0:
		{
			HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);//关
			if(0 == SetDataConfig->TimeDelayOff)
			{//判断关闭时间
				DOstate = 2;
			}
			else
			{
				if(0 == tickstart[TASK_WORK_DO1].start)
				{
					Start_Tick(TASK_WORK_DO1);
					DOstate = 1;
				}
			}
			break;
		}
		case 1:
		{
			if(0 == tickstart[TASK_WORK_DO1].start)
			{
				Start_Tick(TASK_WORK_DO1);
			}
			if((0 != tickstart[TASK_WORK_DO1].start)&&(tickstart[TASK_WORK_DO1].time > SetDataConfig->TimeDelayOff * 100))
			{
				Stop_Tick(TASK_WORK_DO1);
				DOstate = 2;
			}
			break;
		}
		case 2:
		{
			HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_SET);
			if(0 == SetDataConfig->TimeDelayOn)
			{
				DOstate = 3;
			}
			else
			{
				if(0 == tickstart[TASK_WORK_DO1].start)
				{
					Start_Tick(TASK_WORK_DO1);
					DOstate = 3;
				}
			}
			break;
		}
		case 3:
		{
			if((0 != tickstart[TASK_WORK_DO1].start)&&(tickstart[TASK_WORK_DO1].time > SetDataConfig->TimeDelayOn * 100))
			{
				Stop_Tick(TASK_WORK_DO1);
				DOstate = 4;
			}
			break;
		}
		case 4:
		{
			HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);//关
			RunDataConfig->DO = 0;
			break;
		}
	}
}

void LogicStateInit(void)
{
	LogicState = SetDataConfig->Logic;
}


/**/
uint16_t DI0State = 0;//判断DI是否变化

void DOProcess(void)
{//DO输出
	if(LogicState != SetDataConfig->Logic)
	{//切换了逻辑模式 需要把部分参数重新初始化
		LogicState = SetDataConfig->Logic;
		RunDataConfig->DO = 0;
		DOstate = 0;
		Stop_Tick(TASK_WORK_DO1);
	}
	switch(SetDataConfig->Logic)
	{
		case 0:
		{//无逻辑
			if(0 != RunDataConfig->DO)
			{
				DOSetProcess();
			}
			else
			{
				DOstate = 0;
				tickstart[TASK_WORK_DO1].start = 0;
				HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
			}
			break;
		}
		case 1:
		{//延时翻转
			{
				if(0 != RunDataConfig->DO)
				{
					if((0 == SetDataConfig->TimeDelayOn)||(0 == SetDataConfig->TimeDelayOff))
					{
						RunDataConfig->DO = 0;
					}
					else
					{
						if(0 == tickstart[TASK_WORK_DO1].start)
						{
							Start_Tick(TASK_WORK_DO1);
						}
						if((0 == DOOutput)&&(0 != tickstart[TASK_WORK_DO1].start)&&(SetDataConfig->TimeDelayOff * 100 <= tickstart[TASK_WORK_DO1].time))
						{//关闭时间
							DOOutput = 1;
							tickstart[TASK_WORK_DO1].time = 0;
							HAL_GPIO_WritePin(DO1_GPIO_Port,DO1_Pin,GPIO_PIN_SET);
						}
						else if((0 != DOOutput)&&(0 != tickstart[TASK_WORK_DO1].start)&&(SetDataConfig->TimeDelayOn * 100 <= tickstart[TASK_WORK_DO1].time))
						{//开启时间
							DOOutput = 0;
							tickstart[TASK_WORK_DO1].time = 0;
							HAL_GPIO_WritePin(DO1_GPIO_Port,DO1_Pin,GPIO_PIN_RESET);
						}
					}
				}
				else
				{
					DOOutput = 0;
					Stop_Tick(TASK_WORK_DO1);
					HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
				}
				return;
			}
			break;
		}
		case 2:
		{//通电闭合
			if(0==POW_Start)
			{
				POW_Start = 1;
				RunDataConfig->DO = 1;
			}
			else
			{
				if(0 != RunDataConfig->DO)
				{
					DOSetProcess();
				}
				else
				{
					DOstate = 0;
					tickstart[TASK_WORK_DO1].start = 0;
					HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
				}
			}
			break;
		}
		case 3:
		{//掉电保存
			if(0 != POW_Start)
			{
				if(0 != RunDataConfig->DO)
				{
					DOSetProcess();
				}
				else
				{
					DOstate = 0;
					tickstart[TASK_WORK_DO1].start = 0;
					HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
				}
				
				if(SetDataConfig->SaveState != RunDataConfig->DO)
				{
					SetDataConfig->SaveState = RunDataConfig->DO;
					SetDataConfig->ModemSet.Save = 1;
					
				}
			}
			else
			{
				POW_Start=1;
				RunDataConfig->DO = SetDataConfig->SaveState;
			}
			break;
		}
		case 4:
		{//脉冲翻转
			if(0 != RunDataConfig->DO)
			{
				DOSetProcess();
			}
			else
			{
				DOstate = 0;
				tickstart[TASK_WORK_DO1].start = 0;
				HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
			}
			if(DI0State != RunDataConfig->DI0)
			{
				DI0State = RunDataConfig->DI0;
				if(0 != DI0State)
				{
						RunDataConfig->DO = ~RunDataConfig->DO;
				}
			}
			break;
		}
		case 5:
		{//输入跟随
			if((0 != RunDataConfig->DO)&&(0 != RunDataConfig->DI0))
			{
				DOSetProcess();
			}
			else
			{
				RunDataConfig->DO = 0;
				DOstate = 0;
				tickstart[TASK_WORK_DO1].start = 0;
				HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
			}
			if(DI0State != RunDataConfig->DI0)
			{
				DI0State = RunDataConfig->DI0;

				RunDataConfig->DO = DI0State;
			}
			break;
		}
		case 6:
		{//输入取反
			if((0 != RunDataConfig->DO)&&(0 == RunDataConfig->DI0))
			{
				DOSetProcess();
			}
			else
			{
				RunDataConfig->DO = 0;
				DOstate = 0;
				tickstart[TASK_WORK_DO1].start = 0;
				HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
			}
			if(DI0State != RunDataConfig->DI0)
			{
				DI0State = RunDataConfig->DI0;

				RunDataConfig->DO = !DI0State;
			}
			break;
		}
		case 7:
		{//负载模式
			if(0 != RunDataConfig->DO)
			{
				DOSetProcess();
			}
			else
			{
				DOstate = 0;
				tickstart[TASK_WORK_DO1].start = 0;
				HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
			}
			if(DI0State != RunDataConfig->DI0)
			{
				DI0State = RunDataConfig->DI0;
				if(0 == DI0State)
				{
					RunDataConfig->DO = 0;
				}
			}
			break;
		}
		case 8:
		{//限位模式
			if((0 != RunDataConfig->DO)&&(0 == DI0State))
			{
				DOSetProcess();
			}
			else
			{
				DOstate = 0;
				tickstart[TASK_WORK_DO1].start = 0;
				HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
			}
			if(DI0State != RunDataConfig->DI0)
			{
				DI0State = RunDataConfig->DI0;
				if(0 != DI0State)
				{
					RunDataConfig->DO = 0;
				}
			}
			break;
		}
		case 9:
		{//脉冲触发
			if(0 != RunDataConfig->DO)
			{
				DOSetProcess();
			}
			else
			{
				DOstate = 0;
				tickstart[TASK_WORK_DO1].start = 0;
				HAL_GPIO_WritePin(DO1_GPIO_Port, DO1_Pin, GPIO_PIN_RESET);
			}
			if(DI0State != RunDataConfig->DI0)
			{
				DI0State = RunDataConfig->DI0;
				if(0 != DI0State)
				{
					RunDataConfig->DO = 1;
				}
			}
			break;
		}
	}
	POW_Start = 1;
}

/*******LOGIC******/


uint16_t KeyState = 0;//Key状态变化
uint16_t DOState = 0;//DO状态变化

void LogicProcess(void)
{
	//按键控制DO翻转
	if(KeyState != RunDataConfig->Key)
	{//按键状态变化判断
		KeyState = RunDataConfig->Key;
		if(0 != KeyState)
		{
			RunDataConfig->DO = !RunDataConfig->DO;
		}
	}
	//判断DO与DI的状态是否同步
	if((0==tickstart[TASK_WORK_ALME].start)||(DOState != RunDataConfig->DO))
	{
		DOState = RunDataConfig->DO;
		Start_Tick(TASK_WORK_ALME);
	}
	if((tickstart[TASK_WORK_ALME].start)&&(tickstart[TASK_WORK_ALME].time > 500))
	{
		Stop_Tick(TASK_WORK_ALME);
		if(RunDataConfig->DI0 != RunDataConfig->DO)
		{
				RunDataConfig->Police = 1;
		}
		else
		{
			RunDataConfig->Police = 0;
		}
	}
}







/*
 * 主动上报部分
*/

uint16_t RegChenge = 0;
uint16_t RegReport[3] = {0};

void RegReportProcess(void)
{
	if(0 == RegChenge)
	{
		if(0 != AtSendTime)
			{
			if(0 == tickstart[TASK_REG_CHENGE].start)
			{
					Start_Tick(TASK_REG_CHENGE);
			}
			if((tickstart[TASK_REG_CHENGE].start)&&tickstart[TASK_REG_CHENGE].time > 500)
			{
				Stop_Tick(TASK_REG_CHENGE);
				AtSendTime = 0;
			}
		}
		else
		{
			if((RegReport[0] != RunDataConfig->DO)||(RegReport[1] != RunDataConfig->DI0)||(RegReport[2] != RunDataConfig->Police))
			{
				RegReport[0] = RunDataConfig->DO;
				RegReport[1] = RunDataConfig->DI0;
				RegReport[2] = RunDataConfig->Police;
				RegChenge = 1;
			}
		}
	}
}

////////////////////

